import Common
import unittest
import numpy as np

'''
传统数值微分
f:需要微分的函数
x:进行微分的x坐标
eps:精度,间隔
'''
def numerical_diff(f,x,eps=1e-4):
    x0 = Common.Variable(x.data - eps)
    x1 = Common.Variable(x.data + eps)
    y0 = f(x0)
    y1 = f(x1)
    return (y1.data - y0.data) / (2*eps)
    
    

class SquareTest(unittest.TestCase):
    #前向传播测试
    def test_forward(self):
        x = Common.Variable(np.array(2.0))
        y = Common.square(x)
        expected = np.array(4.0)
        self.assertEqual(y.data,expected)
        
    #反向传播测试
    def test_backward(self):
        x = Common.Variable(np.array(3.0))
        y = Common.square(x)
        y.backward()
        expected = np.array(6.0)
        self.assertEqual(x.grad,expected)
        
    #梯度检验测试
    def test_gradient_check(self):
        x = Common.Variable(np.random.rand(1))
        y = Common.square(x)
        y.backward()
        num_grad = numerical_diff(Common.square,x)
        flg = np.allclose(x.grad,num_grad) #np.allclose(a,b)用于判断a和b的值是否接近
        self.assertTrue(flg)
        
unittest.main()
